package com.zodiac.app.gsps.endpoint.common;

import com.alibaba.fastjson.JSON;
import com.github.lzm320a99981e.autocoding.domain.mybatis.TreeableHelper;
import com.github.lzm320a99981e.quickly.starter.Constants;
import com.github.lzm320a99981e.quickly.starter.RequestContextHelper;
import com.github.lzm320a99981e.zodiac.component.tools.IdGenerator;
import com.github.lzm320a99981e.zodiac.component.tools.TreeTransfer;
import com.google.common.collect.Maps;
import com.zodiac.app.gsps.datasource.primary.model.SysDictionary;
import com.zodiac.app.gsps.datasource.primary.service.SysDictionaryService;
import com.zodiac.app.gsps.endpoint.common.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("${" + Constants.ENV_PREFIX + "api.router.public-prefix:/public}")
public class PublicEndpoint {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private SysDictionaryService sysDictionaryService;

    @PostMapping("100101")
    public Object login(@Valid @RequestBody PersonalLoginRequest request) {
        return request;
    }

    @PostMapping("dictionaries1")
    public Object dictionaries1() {
        int idCounter = 1;
        String category = "category";
        List<Dict> dicts = new ArrayList<>();

        Dict shengwu = new Dict(idCounter++, "生物", IdGenerator.uuid32(), category, null);

        Dict zhiwu = new Dict(idCounter++, "植物", IdGenerator.uuid32(), category, shengwu.getId());
        Dict hua = new Dict(idCounter++, "花", IdGenerator.uuid32(), category, zhiwu.getId());
        Dict cao = new Dict(idCounter++, "草", IdGenerator.uuid32(), category, zhiwu.getId());
        Dict shu = new Dict(idCounter++, "数", IdGenerator.uuid32(), category, zhiwu.getId());

        Dict dongwu = new Dict(idCounter++, "动物", IdGenerator.uuid32(), category, shengwu.getId());
        String donwuCategory = "animal";
        Dict laohu = new Dict(idCounter++, "老虎", IdGenerator.uuid32(), donwuCategory, dongwu.getId());
        Dict shizi = new Dict(idCounter++, "狮子", IdGenerator.uuid32(), donwuCategory, dongwu.getId());
        Dict liebao = new Dict(idCounter++, "猎豹", IdGenerator.uuid32(), donwuCategory, dongwu.getId());

        dicts.addAll(Arrays.asList(shengwu, zhiwu, hua, cao, shu, dongwu, laohu, shizi, liebao));

        // chinese area
        Dict area = new Dict(idCounter++, "中国区域", IdGenerator.uuid32(), category, null);
        String areaCategory = "area";

        Dict sheng = new Dict(idCounter++, "省份", IdGenerator.uuid32(), areaCategory, area.getId());
        Dict sheng1 = new Dict(idCounter++, "黑龙江", IdGenerator.uuid32(), areaCategory, sheng.getId());
        Dict shi11 = new Dict(idCounter++, "大庆", IdGenerator.uuid32(), areaCategory, sheng1.getId());
        Dict shi12 = new Dict(idCounter++, "哈尔滨", IdGenerator.uuid32(), areaCategory, sheng1.getId());
        Dict shi13 = new Dict(idCounter++, "牡丹江", IdGenerator.uuid32(), areaCategory, sheng1.getId());
        Dict shi14 = new Dict(idCounter++, "佳木斯", IdGenerator.uuid32(), areaCategory, sheng1.getId());

        Dict sheng2 = new Dict(idCounter++, "吉林", IdGenerator.uuid32(), areaCategory, sheng.getId());
        Dict shi21 = new Dict(idCounter++, "长春", IdGenerator.uuid32(), areaCategory, sheng2.getId());
        Dict shi22 = new Dict(idCounter++, "吉林", IdGenerator.uuid32(), areaCategory, sheng2.getId());
        Dict shi23 = new Dict(idCounter++, "松原", IdGenerator.uuid32(), areaCategory, sheng2.getId());
        Dict shi24 = new Dict(idCounter++, "延吉", IdGenerator.uuid32(), areaCategory, sheng2.getId());

        Dict zhixiashi = new Dict(idCounter++, "直辖市", IdGenerator.uuid32(), areaCategory, area.getId());
        Dict zhixiashi1 = new Dict(idCounter++, "北京", IdGenerator.uuid32(), areaCategory, zhixiashi.getId());
        Dict zhixiashi2 = new Dict(idCounter++, "天津", IdGenerator.uuid32(), areaCategory, zhixiashi.getId());
        Dict zhixiashi3 = new Dict(idCounter++, "上海", IdGenerator.uuid32(), areaCategory, zhixiashi.getId());
        Dict zhixiashi4 = new Dict(idCounter++, "重庆", IdGenerator.uuid32(), areaCategory, zhixiashi.getId());

        Dict zizhiqu = new Dict(idCounter++, "自治区", IdGenerator.uuid32(), areaCategory, area.getId());
        Dict zizhiqu1 = new Dict(idCounter++, "新疆", IdGenerator.uuid32(), areaCategory, zizhiqu.getId());
        Dict zizhiqu2 = new Dict(idCounter++, "内蒙古", IdGenerator.uuid32(), areaCategory, zizhiqu.getId());
        Dict zizhiqu3 = new Dict(idCounter++, "西藏", IdGenerator.uuid32(), areaCategory, zizhiqu.getId());
        Dict zizhiqu4 = new Dict(idCounter++, "宁夏", IdGenerator.uuid32(), areaCategory, zizhiqu.getId());
        Dict zizhiqu5 = new Dict(idCounter++, "广西", IdGenerator.uuid32(), areaCategory, zizhiqu.getId());

        dicts.addAll(Arrays.asList(
                area, sheng, sheng1, sheng2, shi11, shi12, shi13, shi14, shi21, shi22, shi23, shi24, zhixiashi, zhixiashi1, zhixiashi2, zhixiashi3, zhixiashi4, zizhiqu, zizhiqu1, zizhiqu2, zizhiqu3, zizhiqu4, zizhiqu5
        ));

        // 字典类别
        List<Dict> categories = dicts.stream().filter(item -> item.getCategory().equals(category)).collect(Collectors.toList());
        // 字典条目
        List<Dict> dictItems = dicts.stream().filter(item -> !item.getCategory().equals(category)).collect(Collectors.toList());

        HashMap<String, Object> result = Maps.newHashMap();
        result.put("categories", TreeTransfer.create().parentKey("parentId").transform(categories));
        result.put("dictItems", TreeTransfer.create().parentKey("parentId").transform(dictItems).stream().collect(Collectors.groupingBy(Dict::getParentId)));

        return result;
    }

    @PostMapping("dictionaries")
    public DictionaryQueryResponse dictionaries() {
        final DictionaryQueryResponse response = new DictionaryQueryResponse();
        final SysDictionary root = sysDictionaryService.selectRoot();

        if (Objects.isNull(root)) {
            return response;
        }

        final List<SysDictionary> topDictionaries = sysDictionaryService.selectChildren(root, false);
        if (topDictionaries.isEmpty()) {
            return response;
        }
        response.setCategories(topDictionaries);

        List<SysDictionary> dictionaries = sysDictionaryService.selectChildren(root, true);
        response.setDictionaries(TreeableHelper.hierarchical(dictionaries));
        response.setParentIdWithChildrenMap(TreeableHelper.hierarchical(dictionaries).stream().collect(Collectors.toMap(SysDictionary::getId, SysDictionary::getChildren)));

        return response;
    }

    @PostMapping("createDictionaryCategory")
    public SysDictionary createDictionaryCategory(@Valid @RequestBody DictionaryCategoryCreateRequest request) {
        final String name = request.getName();
        final String code = request.getCode();

        SysDictionary root = sysDictionaryService.selectRoot();
        SysDictionary newCategory = new SysDictionary();
        newCategory.setCategory(code);
        newCategory.setName(name);
        newCategory.setExtNodeParentId(root.getId());

        sysDictionaryService.insertSelective(newCategory);

        return newCategory;
    }


    @PostMapping("updateDictionaryCategory")
    public SysDictionary updateDictionaryCategory(@Valid @RequestBody DictionaryCategoryUpdateRequest request) {
        SysDictionary toUpdate = new SysDictionary();
        toUpdate.setId(request.getId());
        toUpdate.setName(request.getName());
        sysDictionaryService.updateByPrimaryKeySelective(toUpdate);
        return toUpdate;
    }

    @PostMapping("createDictionary")
    public SysDictionary createDictionary(@Valid @RequestBody DictionaryCreateRequest request) {
        SysDictionary parent = sysDictionaryService.selectByPrimaryKey(request.getParentId());
        SysDictionary newDictionary = new SysDictionary();
        newDictionary.setCategory(parent.getCategory());
        newDictionary.setName(request.getName());
        newDictionary.setExtNodeParentId(parent.getId());
        sysDictionaryService.insertSelective(newDictionary);

        return newDictionary;
    }

    @PostMapping("updateDictionary")
    public SysDictionary updateDictionary(@Valid @RequestBody DictionaryUpdateRequest request) {
        SysDictionary toUpdate = new SysDictionary();
        toUpdate.setId(request.getId());
        toUpdate.setName(request.getName());
        sysDictionaryService.updateByPrimaryKeySelective(toUpdate);
        return toUpdate;
    }

    @PostMapping("deleteDictionary")
    public SysDictionary deleteDictionary(@Valid @RequestBody DictionaryDeleteRequest request) {
        SysDictionary toDelete = sysDictionaryService.selectByPrimaryKey(request.getId());
        sysDictionaryService.deleteByPrimaryKey(toDelete.getId());
        return toDelete;
    }

    @PostMapping("deleteDictionaryCategory")
    public SysDictionary deleteDictionaryCategory(@Valid @RequestBody DictionaryCategoryDeleteRequest request) {
        SysDictionary toDelete = sysDictionaryService.selectByPrimaryKey(request.getId());
        sysDictionaryService.deleteByPrimaryKey(toDelete.getId());
        return toDelete;
    }

    @PostMapping("cache-test")
    public Object cacheTest(@Valid @RequestBody PersonalLoginRequest request) {
        redisTemplate.opsForValue().set("cache-test1", request);
        final Object result = redisTemplate.opsForValue().get("cache-test1");
        System.out.println(result);
        return request;
    }

    @Cacheable(cacheNames = "test01")
    @PostMapping("cache-test2")
    public Map test2(@RequestBody PersonalLoginRequest request) {
        return (Map) JSON.toJSON(request);
    }

    @PostMapping("share-cookie-test")
    public Map shareCookieTest(@RequestBody Map<String, Object> request) {
        log.info("请求头信息 -> {}", JSON.toJSONString(RequestContextHelper.getHeaderMap(), true));
        return request;
    }

}
